<!-- 创作会话 -->

<template>
	<div style="height: 85vh">
		<a-row :gutter="24" type="flex" align="stretch" style="height: 100%">
			<a-col :span="24" :lg="8" class="mb-24">
				<a-card :bordered="false" class="header-solid h-full" style="display: flex; flex-direction: column" :bodyStyle="{ padding: '0 24px 24px', flex: 1 }">
					<template #title>
						<a-row type="flex" align="middle" justify="center">
							<a-col>
								<h5 class="font-semibold m-0">{{ detail.title }}</h5>
							</a-col>
						</a-row>
					</template>
					<div class="form_box">
						<div class="form_line" v-for="(item, index) in detail.extend" :key="'form_line_' + index">
							<div class="label">
								<span :class="{ require: item.require == 1 }">{{ item.title }}</span>
							</div>
							<div class="content" v-if="item.field == 'string'">
								<a-input v-model="item.value" :placeholder="item.tip" />
							</div>
							<div class="content" v-if="item.field == 'number'">
								<a-input v-model="item.value" :placeholder="item.tip" />
							</div>
							<div class="content" v-if="item.field == 'textarea'">
								<a-textarea v-model="item.value" :placeholder="item.tip" :auto-size="{ minRows: 3, maxRows: 5 }" />
							</div>
							<div class="content" v-if="item.field == 'select'">
								<a-input-group>
									<a-select style="width: 100%" :placeholder="item.tip" :defaultValue="item.value" @change="item.value = $event">
										<a-select-option :value="o" v-for="(o, i) in item.selects" :key="'option_' + index + '_' + i">{{ o }}</a-select-option>
									</a-select>
								</a-input-group>
							</div>
						</div>
						<div class="label" style="margin-bottom: 10px;">
						    关联知识库文档
						</div>
						  <a-select default-value="0" style="width: 100%;margin-bottom: 10px;" @change="handleChange" >
							  <a-select-option value="0" >
							    不关联
							  </a-select-option>
						      <a-select-option :value="value.id"  v-for="(value,index) in history_data">
						        {{value.pdf_name}}
						      </a-select-option>
						    </a-select>
							<a href="/#/ai_pdf" style="float: right;">没有文档？去上传</a>
						<div class="form_tools">
							<a-radio-group v-model="modeType" button-style="" size="small">
								<a-radio-button :value="item.type" v-for="(item, index) in modeList" :key="'g_mode_' + index">{{ item.name }}（{{ item.usable }}积分）</a-radio-button>
							</a-radio-group>
						</div>
						
						<div class="form_button">
							<a-button type="primary" block :disabled="disabled" @click="submitHandle"> 生成内容 </a-button>
						</div>
						<div style="margin-top: 20px;color: #ccc;font-size: 12px;" v-if="detail.user_id">
							作者：<a-avatar :src="detail.user_img" style="height: 18px;width: 18px;margin-right: 5px;" />{{detail.user_name}}
							<br>发布于：{{detail.createtime}}
						</div>
						<a-collapse style="width: 100%;margin-top: 10px;">
						        <a-collapse-panel header="历史记录"  key="1" >
									<div style="height: 200px;overflow-y: auto;">
						            <div class="advanced_box"  v-for="(item, index) in contentlist">
						                <div style="margin-top: 5px;padding: 5px;" @click="takewritelist(index)"><span style="display: block;     color:#1890ff;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;width: 260px;">{{item.message}}</span></div>
						            </div>
									</div>
						        </a-collapse-panel>
						    </a-collapse>
					</div>
				</a-card>
			</a-col>
			<a-col :span="24" :lg="16" class="mb-24">
				<a-card :bordered="false" class="header-solid h-full" style="display: flex; flex-direction: column" :bodyStyle="{ padding: '34px 14px 34px 24px', flex: 1, position: 'relative' }">
					<!-- <template #title v-if="titleText && dataText">
						<a-row type="flex" align="middle" justify="center">
							<a-col>
								<h5 class="font-semibold m-0">标题：{{ titleText }}</h5>
							</a-col>
						</a-row>
					</template> -->
					<div class="content_box">
						<div v-if="dataText" id="bom" ref="svgContainer">
							<v-md-editor v-model="dataText" mode="preview"></v-md-editor>
						</div>
						<div v-else>
							<div v-if="disabled">
								<a-icon type="loading" :style="{ fontSize: '26px' }" />
							</div>
							<div v-else>欢迎使用AI创作！</div>
						</div>

						<div class="copy" v-if="!disabled && dataText" @click="copyHandle">
							<a-button type="primary" shape="circle" class="c_button">
								<a-icon type="copy" theme="filled" :style="{ fontSize: '16px', margin: 0 }" />
							</a-button>
						</div>
						<div class="copy" style="margin-right: 50px;" v-if="!disabled && dataText" @click="exportToWord">
							<a-button type="primary" shape="circle" class="c_button">
								<a-icon type="file-word" theme="filled" :style="{ fontSize: '16px', margin: 0 }" />
							</a-button>
						</div>
						<div class="copy" style="margin-right: 100px;" v-if="!disabled && dataText" @click="exportTopng">
							<a-button type="primary" shape="circle" class="c_button">
								<a-icon type="file-image" theme="filled" :style="{ fontSize: '16px', margin: 0 }" />
							</a-button>
						</div>
					</div>
				</a-card>
			</a-col>
		</a-row>
	</div>
</template>

<script setup>
	import { mapState, mapGetters, mapMutations, mapActions } from "vuex"
	import htmlDocx from "html-docx-js/dist/html-docx";
	import html2canvas from 'html2canvas';
	export default {
		data() {
			return {
				query: {},
				detail: {},
				dataText: "",
				disabled: false,
				titleText: "",
				modeList: [], // 模型列表
				modeType: "" ,// 选中模型
				history_data:[],
				zsk_id:0,
				contentlist:[],
			}
		},
		computed: {
			...mapGetters("user", ["token"])
		},
		created() {
			this.getUserInfo()
			this.query = this.$route.query
			this.query.id && this.writeClassifyDetail()
			this.getModeList()
			this.getUserPdf()
			this.getwritelist()
		},
		mounted() {},
		methods: {
			...mapActions("user", ["getUserInfo"]),
			// 获取GPT模型
			getUserPdf(){
			    this.$http("role.getpdf").then(res => {
			        if(res.code == 1){
			            this.history_data = res.data;
			        }
			
			    })
			},
			handleChange(value){
				this.zsk_id = value;
			},
			getModeList() {
				this.$http("chat.mode").then(res => {
					if (res.code === 1) {
						this.modeList = res.data
						this.modeType = res.data[0].type
					}
				})
			},
			getwritelist(){
				this.$http("write.record", {prompt_id:this.query.id}).then(res => {
					if (res.code === 1) {
						this.contentlist =res.data
					}else{
						 this.$message.warning(res.msg)
					}
				})
			},
			takewritelist(id){
						 this.dataText = this.contentlist[id].response;
			},
			exportToWord() {
			        const ood = 'bom'
			        const content =document.getElementById(ood).innerHTML
			        const converted = htmlDocx.asBlob(content)
			        const url = window.URL.createObjectURL(converted)
					const a = document.createElement("a");
					a.href = url;
					a.download = '导出文件.docx';
					a.click();
					URL.revokeObjectURL(url);
			    },
			 async  exportTopng(){
				const canvas =  await html2canvas(this.$refs.svgContainer);
				this.pngData = canvas.toDataURL('image/png');
				// 将 Base64 格式的图片数据转换为 Blob 对象
				  const blob = this.dataURLToBlob(this.pngData);
				
				  // 创建下载链接并模拟点击下载
				  const downloadLink = document.createElement('a');
				  downloadLink.href = URL.createObjectURL(blob);
				  downloadLink.download = 'exported-image.png'; // 设置下载文件名
				  document.body.appendChild(downloadLink);
				  downloadLink.click();
				
				  // 清理：移除添加的下载链接并释放对象 URL 资源
				  document.body.removeChild(downloadLink);
				  URL.revokeObjectURL(downloadLink.href);
			},
			dataURLToBlob(dataURL) {
			  const base64Marker = ';base64,';
			  const data = dataURL.split(base64Marker)[1];
			  const contentType = dataURL.split(',')[0].split(':')[1];
			  const raw = window.atob(data);
			  const rawLength = raw.length;
			  const uInt8Array = new Uint8Array(rawLength);
			
			  for (let i = 0; i < rawLength; ++i) {
			    uInt8Array[i] = raw.charCodeAt(i);
			  }
			
			  return new Blob([uInt8Array], { type: contentType });
			},
			// 复制
			async copyHandle() {
				try {
					await navigator.clipboard.writeText(this.dataText)
					this.$message.success("已复制到剪切板")
				} catch (err) {
					this.$message.error("复制失败")
				}
			},
			// 提交
			submitHandle() {
				const verify = this.detail.extend.filter(item => item.require == 1 && !item.value).map(item => item.name)
				if (verify.length) return this.$message.error("必填项为空!")
				if (!this.modeType) return this.$message.error("会话模型错误，请联系管理员")

				const obj = {
					type: "write",
					prompt_id: this.query.id,
					params: {},
					message: "",
					mode: this.modeType,
					zskid:this.zsk_id
				}
				this.detail.extend.map(item => {
					obj.params[item.name] = item.value
					if (item.value) {
						obj.message += `${item.title}: ${item.value} \n\n`
					}
					if (item.name == "title") {
						this.titleText = item.value
					}
				})

				this.fetchDataStream(obj)
			},
			// 发送请求
			async fetchDataStream(message) {
				if (!message) {
					console.log("输入为空")
					return
				}
				this.dataText = ""
				this.disabled = true
				const postData = message,
					url = this.$BASE_API + "/addons/chatgpt/web/sendText",
					controller = new AbortController(),
					Token = this.token,
					Sign = window.location.search.replace(/\?/g, "")

				try {
					const response = await fetch(url, {
						method: "post",
						headers: {
							"Content-Type": "application/json;charset=utf-8",
							Token,
							Sign
						},
						body: JSON.stringify(postData),
						signal: controller.signal
					})

					const reader = response.body.getReader()
					let data = ""

					while (true) {
						const { done, value } = await reader.read(),
							str = new TextDecoder().decode(value)

						if (str.indexOf("data: [DONE]") != -1 || str.indexOf("data:[DONE]") != -1 || done) {
							const arr = str.replaceAll(" ", "").split("data:[DONE]")
							if (arr[0].length) {
								this.dataText += arr[0]
							}
							this.disabled = false
							break
						}
						data += str
						this.dataText = data
					}
				} catch {
					console.error("请求失败")
				}
			},
			writeClassifyDetail() {
				this.$http("write.detail", { prompt_id: this.query.id }).then(res => {
					if (res.code === 1) {
						this.detail = res.data
					}
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
	::-webkit-scrollbar {
		width: 16px;
	}

	::-webkit-scrollbar-thumb {
		border-radius: 12px;
		border: 6px solid rgba(0, 0, 0, 0);
		box-shadow: 8px 0 0 #a5adb7 inset;
	}

	::-webkit-scrollbar-thumb:hover {
		box-shadow: 8px 0 0 #4a4a4a inset;
	}

	.form_box {
		height: 0;
		min-height: 100%;
		overflow-y: auto;
		overflow-x: hidden;

		.form_line {
			margin-bottom: 20px;
			.label {
				margin-bottom: 10px;

				span {
					position: relative;

					&.require {
						&::before {
							content: "*";
							position: absolute;
							top: 0;
							right: -10px;
							color: red;
						}
					}
				}
			}
		}

		.form_button {
			margin-top: 20px;
			display: flex;
			align-items: center;
			justify-content: center;
		}
	}

	.content_box {
		height: 0;
		min-height: 100%;
		overflow-y: auto;
		overflow-x: hidden;

		::v-deep .vuepress-markdown-body {
			padding: 0 20px;
		}

		.copy {
			position: absolute;
			bottom: 50px;
			right: 40px;
			z-index: 1;
			.c_button {
				background: rgba(#1890ff, 1);
			}
			::v-deep .ant-btn svg {
				margin-right: 0;
			}
		}
	}
</style>
